The attached patch removes all of the console handling code from Xend
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 4 Aug 2005 09:00:16 +0000 (09:00 +0000)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 4 Aug 2005 09:00:16 +0000 (09:00 +0000)
and changes xm to simply exec /usr/libexec/xen/xc_console.

I've done a pretty good amount of testing and this seems to clear up all
of the Xend console issues in bugzilla.

This is a pretty big change to Xend though with a lot of deleted code so
I'd appreciate if people more familiar with the Xend codebase could look
through it critically.

In addition to the patch, the following files are no longer used:

tools/python/xen/util/console_client.py
tools/python/xen/xend/XendConsole.py
tools/python/xen/xend/server/SrvConsole.py
tools/python/xen/xend/server/SrvConsoleDir.py
tools/python/xen/xend/server/console.py

Regards,

Anthony Liguori

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
17 files changed:
tools/Makefile
tools/misc/xend
tools/python/xen/util/console_client.py [deleted file]
tools/python/xen/xend/XendClient.py
tools/python/xen/xend/XendConsole.py [deleted file]
tools/python/xen/xend/XendDomainInfo.py
tools/python/xen/xend/XendRoot.py
tools/python/xen/xend/server/SrvConsole.py [deleted file]
tools/python/xen/xend/server/SrvConsoleDir.py [deleted file]
tools/python/xen/xend/server/SrvDomain.py
tools/python/xen/xend/server/SrvRoot.py
tools/python/xen/xend/server/SrvServer.py
tools/python/xen/xend/server/console.py [deleted file]
tools/python/xen/xend/server/event.py
tools/python/xen/xend/server/messages.py
tools/python/xen/xm/create.py
tools/python/xen/xm/main.py

index 2c668a59b967cdddfc930842b53eebd9ff28166e..629294e7768a52df9bc67e8beb6eddb4e5bd3ca8 100644 (file)
@@ -13,7 +13,7 @@ SUBDIRS += xcutils
 #SUBDIRS += pygrub
 SUBDIRS += firmware
 SUBDIRS += security
-#SUBDIRS += consoled
+SUBDIRS += consoled
 
 .PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean
 
index 06f5e660ec3585172a978bc674da8e98cff63a00..706c83842870e84fa164a343e949598b885a0749 100644 (file)
@@ -130,6 +130,8 @@ def main():
         return status >> 8
     elif sys.argv[1] == 'start':
         start_xcs()
+        if os.fork() == 0:
+            os.execvp('/usr/sbin/consoled', ['/usr/sbin/consoled']);
         return daemon.start()
     elif sys.argv[1] == 'trace_start':
         start_xcs()
diff --git a/tools/python/xen/util/console_client.py b/tools/python/xen/util/console_client.py
deleted file mode 100644 (file)
index c0acacf..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-#!/usr/bin/env python
-
-##############################################
-# Console client for Xen guest OSes
-# Copyright (c) 2004, K A Fraser
-##############################################
-
-import errno, os, signal, socket, struct, sys
-
-from termios import *
-# Indexes into termios.tcgetattr() list.
-IFLAG  = 0
-OFLAG  = 1
-CFLAG  = 2
-LFLAG  = 3
-ISPEED = 4
-OSPEED = 5
-CC     = 6
-
-def __child_death(signum, frame):
-    global stop
-    stop = True
-
-def __recv_from_sock(sock):
-    global stop
-    stop = False
-    while not stop:
-        try:
-            data = sock.recv(1024)
-        except socket.error, error:
-            if error[0] != errno.EINTR:
-                raise
-        else:
-            try:
-                os.write(1, data)
-            except os.error, error:
-                if error[0] != errno.EINTR:
-                    raise
-    os.wait()
-
-def __send_to_sock(sock):
-    while 1:
-        try:
-            data = os.read(0,1024)
-        except os.error, error:
-            if error[0] != errno.EINTR:
-                raise
-        else:
-            if ord(data[0]) == ord(']')-64:
-                break
-            try:
-                sock.send(data)
-            except socket.error, error:
-                if error[0] == errno.EPIPE:
-                    sys.exit(0)
-                if error[0] != errno.EINTR:
-                    raise
-    sys.exit(0)
-
-def connect(host, port, path=None):
-    # Try inet first. If 'path' is given and the error
-    # was connection refused, try unix-domain on 'path'.
-    try:
-        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        sock.connect((host, port))
-    except socket.error, err:
-        if (path is None) or (err[0] != errno.ECONNREFUSED):
-            raise
-        # Try unix-domain.
-        sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-        sock.connect(path)
-
-    oattrs = tcgetattr(0)
-    nattrs = tcgetattr(0)
-    nattrs[IFLAG] = nattrs[IFLAG] & ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON)
-    nattrs[OFLAG] = nattrs[OFLAG] & ~(OPOST)
-    nattrs[CFLAG] = nattrs[CFLAG] & ~(CSIZE | PARENB)
-    nattrs[CFLAG] = nattrs[CFLAG] | CS8
-    nattrs[LFLAG] = nattrs[LFLAG] & ~(ECHO | ICANON | IEXTEN | ISIG)
-    nattrs[CC][VMIN] = 1
-    nattrs[CC][VTIME] = 0
-
-    if os.fork():
-        signal.signal(signal.SIGCHLD, __child_death)
-        print "************ REMOTE CONSOLE: CTRL-] TO QUIT ********"
-        tcsetattr(0, TCSAFLUSH, nattrs)
-        try:
-            __recv_from_sock(sock)
-        finally:
-            tcsetattr(0, TCSAFLUSH, oattrs)
-            print
-            print "************ REMOTE CONSOLE EXITED *****************"
-    else:
-        signal.signal(signal.SIGPIPE, signal.SIG_IGN)
-        __send_to_sock(sock)
-
-if __name__ == '__main__':
-    argc = len(sys.argv)
-    if argc < 3 or argc > 4:
-        print >>sys.stderr, sys.argv[0], "<host> <port> [<path>]"
-        sys.exit(1)
-    host = sys.argv[1]
-    port = int(sys.argv[2])
-    if argc > 3:
-        path = sys.argv[3]
-    else:
-        path = None
-    connect(host, port, path=path)
index 24812f4abbd4e5425940c2d4cec1281456683b71..868836c30fa932cc44763121212d30b2f0b681a4 100644 (file)
@@ -5,9 +5,7 @@ Callable as a script - see main().
 Supports inet or unix connection to xend.
 
 This API is the 'control-plane' for xend.
-The 'data-plane' is done separately. For example, consoles
-are accessed via sockets on xend, but the list of consoles
-is accessible via this API.
+The 'data-plane' is done separately.
 """
 import os
 import sys
@@ -146,9 +144,6 @@ class Xend:
     def domainurl(self, id=''):
         return self.url.relative('domain/' + str(id))
 
-    def consoleurl(self, id=''):
-        return self.url.relative('console/' + str(id))
-
     def deviceurl(self, id=''):
         return self.url.relative('device/' + str(id))
 
@@ -318,16 +313,6 @@ class Xend:
                               'idx'     : idx,
                               'config'  : fileof(config) })
 
-    def xend_consoles(self):
-        return self.xendGet(self.consoleurl())
-
-    def xend_console(self, id):
-        return self.xendGet(self.consoleurl(id))
-
-    def xend_console_disconnect(self, id):
-        return self.xendPost(self.consoleurl(id),
-                             {'op'      : 'disconnect'})
-
     def xend_vnets(self):
         return self.xendGet(self.vneturl())
 
diff --git a/tools/python/xen/xend/XendConsole.py b/tools/python/xen/xend/XendConsole.py
deleted file mode 100644 (file)
index 7a04f5d..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
-
-import XendRoot; xroot = XendRoot.instance()
-from XendError import XendError
-
-class XendConsole:
-
-    def  __init__(self):
-        pass
-
-    def console_ls(self):
-        return [ c.console_port for c in self.consoles() ]
-
-    def consoles(self):
-        l = []
-        xd = XendRoot.get_component('xen.xend.XendDomain')
-        for vm in xd.list():
-            ctrl = vm.getDeviceController("console", error=False)
-            if (not ctrl): continue
-            console = ctrl.getDevice(0)
-            if (not console): continue
-            l.append(console)
-        return l
-    
-    def console_get(self, id):
-        id = int(id)
-        for c in self.consoles():
-            if c.console_port == id:
-                return c
-        return None
-
-    def console_disconnect(self, id):
-        console = self.console_get(id)
-        if not console:
-            raise XendError('Invalid console id')
-        console.disconnect()
-
-def instance():
-    global inst
-    try:
-        inst
-    except:
-        inst = XendConsole()
-    return inst
index f846bb72de797d9698154d604ed8935acff59706..3e016b681f7b845441a4f5c54225f153e54c07ef 100644 (file)
@@ -268,7 +268,6 @@ class XendDomainInfo:
         self.restart_time = None
         self.restart_count = 0
         
-        self.console_port = None
         self.vcpus = 1
         self.bootloader = None
 
@@ -344,9 +343,6 @@ class XendDomainInfo:
         s += " name=" + self.name
         s += " memory=" + str(self.memory)
         s += " ssidref=" + str(self.ssidref)
-        console = self.getConsole()
-        if console:
-            s += " console=" + str(console.console_port)
         s += ">"
         return s
 
@@ -443,9 +439,6 @@ class XendDomainInfo:
             sxpr.append(self.store_channel.sxpr())
         if self.store_mfn:
             sxpr.append(['store_mfn', self.store_mfn])
-        console = self.getConsole()
-        if console:
-            sxpr.append(console.sxpr())
 
         if self.restart_count:
             sxpr.append(['restart_count', self.restart_count])
@@ -519,7 +512,6 @@ class XendDomainInfo:
 
             # Create domain devices.
             self.configure_backends()
-            self.configure_console()
             self.configure_restart()
             self.construct_image()
             self.configure()
@@ -785,17 +777,6 @@ class XendDomainInfo:
         """
         self.bootloader = sxp.child_value(self.config, "bootloader")
 
-    def configure_console(self):
-        """Configure the vm console port.
-        """
-        x = sxp.child_value(self.config, 'console')
-        if x:
-            try:
-                port = int(x)
-            except:
-                raise VmError('invalid console:' + str(x))
-            self.console_port = port
-
     def configure_restart(self):
         """Configure the vm restart mode.
         """
@@ -855,7 +836,7 @@ class XendDomainInfo:
 
     def restart(self):
         """Restart the domain after it has exited.
-        Reuses the domain id and console port.
+        Reuses the domain id
 
         """
         try:
@@ -910,25 +891,9 @@ class XendDomainInfo:
 
         """
         self.configure_fields()
-        self.create_console()
         self.create_devices()
         self.create_blkif()
 
-    def create_console(self):
-        console = self.getConsole()
-        if not console:
-            config = ['console']
-            if self.console_port:
-                config.append(['console_port', self.console_port])
-            console = self.createDevice('console', config)
-        return console
-
-    def getConsole(self):
-        console_ctrl = self.getDeviceController("console", error=False)
-        if console_ctrl:
-            return console_ctrl.getDevice(0)
-        return None
-
     def create_blkif(self):
         """Create the block device interface (blkif) for the vm.
         The vm needs a blkif even if it doesn't have any disks
@@ -1048,7 +1013,6 @@ add_config_handler('memory',     vm_field_ignore)
 add_config_handler('ssidref',    vm_field_ignore)
 add_config_handler('cpu',        vm_field_ignore)
 add_config_handler('cpu_weight', vm_field_ignore)
-add_config_handler('console',    vm_field_ignore)
 add_config_handler('restart',    vm_field_ignore)
 add_config_handler('image',      vm_field_ignore)
 add_config_handler('device',     vm_field_ignore)
@@ -1062,9 +1026,6 @@ add_config_handler('maxmem',     vm_field_maxmem)
 #============================================================================
 # Register device controllers and their device config types.
 
-from server import console
-controller.addDevControllerClass("console", console.ConsoleController)
-
 from server import blkif
 controller.addDevControllerClass("vbd", blkif.BlkifController)
 add_device_handler("vbd", "vbd")
index 3d3767f9ba64ea0c2bb8004f7ed89aca498f096a..57d5fe6848795793e010e3220fe3bdf97b250e75 100644 (file)
@@ -70,12 +70,6 @@ class XendRoot:
     """Default path the unix-domain server listens at."""
     xend_unix_path_default = '/var/lib/xend/xend-socket'
 
-    """Default interface address xend listens at for consoles."""
-    console_address_default   = 'localhost'
-
-    """Default port xend serves consoles at. """
-    console_port_base_default = '9600'
-
     dom0_min_mem_default = '0'
 
     dom0_cpus_default = '0'
@@ -302,19 +296,6 @@ class XendRoot:
         """
         return self.get_config_value("xend-unix-path", self.xend_unix_path_default)
 
-    def get_console_address(self):
-        """Get the address xend listens at for its console ports.
-        This defaults to 'localhost', allowing only the localhost to connect
-        to the console ports.  Setting this to the empty string, allows all
-        hosts to connect.
-        """
-        return self.get_config_value('console-address', self.console_address_default)
-
-    def get_console_port_base(self):
-        """Get the base port number used to generate console ports for domains.
-        """
-        return self.get_config_int('console-port-base', self.console_port_base_default)
-
     def get_block_script(self, type):
         return self.get_config_value('block-%s' % type, '')
 
diff --git a/tools/python/xen/xend/server/SrvConsole.py b/tools/python/xen/xend/server/SrvConsole.py
deleted file mode 100644 (file)
index f147f28..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
-
-from xen.xend import sxp
-from xen.xend import XendConsole
-from xen.web.SrvDir import SrvDir
-
-class SrvConsole(SrvDir):
-    """An individual console.
-    """
-
-    def __init__(self, info):
-        SrvDir.__init__(self)
-        self.info = info
-        self.xc = XendConsole.instance()
-
-    def op_disconnect(self, op, req):
-        val = self.xc.console_disconnect(self.info.console_port)
-        return val
-
-    def render_POST(self, req):
-        return self.perform(req)
-        
-    def render_GET(self, req):
-        if self.use_sxp(req):
-            req.setHeader("Content-Type", sxp.mime_type)
-            sxp.show(self.info.sxpr(), out=req)
-        else:
-            req.write('<html><head></head><body>')
-            self.print_path(req)
-            #self.ls()
-            req.write('<p>%s</p>' % self.info)
-            req.write('<p><a href="%s">Connect to domain %d</a></p>'
-                      % (self.info.uri(), self.info.id))
-            self.form(req)
-            req.write('</body></html>')
-
-    def form(self, req):
-        req.write('<form method="post" action="%s">' % req.prePathURL())
-        if self.info.connected():
-            req.write('<input type="submit" name="op" value="disconnect">')
-        req.write('</form>')
diff --git a/tools/python/xen/xend/server/SrvConsoleDir.py b/tools/python/xen/xend/server/SrvConsoleDir.py
deleted file mode 100644 (file)
index 5c15eeb..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
-
-from xen.web.SrvDir import SrvDir
-from SrvConsole import SrvConsole
-from xen.xend import XendConsole
-from xen.xend import sxp
-
-class SrvConsoleDir(SrvDir):
-    """Console directory.
-    """
-
-    def __init__(self):
-        SrvDir.__init__(self)
-        self.xconsole = XendConsole.instance()
-
-    def console(self, x):
-        val = None
-        try:
-            info = self.xconsole.console_get(x)
-            val = SrvConsole(info)
-        except KeyError, ex:
-            print 'SrvConsoleDir>', ex
-            pass
-        return val
-
-    def get(self, x):
-        v = SrvDir.get(self, x)
-        if v is not None:
-            return v
-        v = self.console(x)
-        return v
-
-    def render_GET(self, req):
-        if self.use_sxp(req):
-            req.setHeader("Content-Type", sxp.mime_type)
-            self.ls_console(req, 1)
-        else:
-            req.write("<html><head></head><body>")
-            self.print_path(req)
-            self.ls(req)
-            self.ls_console(req)
-            #self.form(req.wfile)
-            req.write("</body></html>")
-
-    def ls_console(self, req, use_sxp=0):
-        url = req.prePathURL()
-        if not url.endswith('/'):
-            url += '/'
-        if use_sxp:
-            consoles = self.xconsole.console_ls()
-            sxp.show(consoles, out=req)
-        else:
-            consoles = self.xconsole.consoles()
-            consoles.sort(lambda x, y: cmp(x.console_port, y.console_port))
-            req.write('<ul>')
-            for c in consoles:
-                cid = str(c.console_port)
-                req.write('<li><a href="%s%s"> %s</a></li>' % (url, cid, cid))
-            req.write('</ul>')
index fc8fd4420b608e619f7f7945e75a4ec21ab1e577..6e51e6951875c9591cf1b80c47056933ae87b5ed 100644 (file)
@@ -4,7 +4,6 @@ from xen.web import http
 
 from xen.xend import sxp
 from xen.xend import XendDomain
-from xen.xend import XendConsole
 from xen.xend import PrettyPrint
 from xen.xend.Args import FormFn
 
@@ -18,7 +17,6 @@ class SrvDomain(SrvDir):
         SrvDir.__init__(self)
         self.dom = dom
         self.xd = XendDomain.instance()
-        self.xconsole = XendConsole.instance()
 
     def op_configure(self, op, req):
         """Configure an existing domain.
@@ -208,14 +206,6 @@ class SrvDomain(SrvDir):
             self.print_path(req)
             #self.ls()
             req.write('<p>%s</p>' % self.dom)
-            if self.dom.console:
-                cinfo = self.dom.console
-                cid = str(cinfo.console_port)
-                #todo: Local xref: need to know server prefix.
-                req.write('<p><a href="/xend/console/%s">Console %s</a></p>'
-                          % (cid, cid))
-                req.write('<p><a href="%s">Connect to console</a></p>'
-                          % cinfo.uri())
             if self.dom.config:
                 req.write("<code><pre>")
                 PrettyPrint.prettyprint(self.dom.config, out=req)
index 84ef0081184d50a78f47a0b9597af65e6ba6ca1c..3c92f5d692b71480ad5fe9a631a34df630476267 100644 (file)
@@ -15,7 +15,6 @@ class SrvRoot(SrvDir):
     subdirs = [
         ('node',    'SrvNode'       ),
         ('domain',  'SrvDomainDir'  ),
-        ('console', 'SrvConsoleDir' ),
         ('vnet',    'SrvVnetDir'    ),
         ]
 
index 1816c1c56dead82398121d69e800cc1623123255..2c87e104de3698a412c19e3140139603071e532f 100644 (file)
@@ -1,7 +1,7 @@
 #!/usr/bin/python
 # Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
 
-"""Example xend HTTP and console server.
+"""Example xend HTTP
 
    Can be accessed from a browser or from a program.
    Do 'python SrvServer.py' to run the server.
diff --git a/tools/python/xen/xend/server/console.py b/tools/python/xen/xend/server/console.py
deleted file mode 100755 (executable)
index e0aa04a..0000000
+++ /dev/null
@@ -1,391 +0,0 @@
-# Copyright (C) 2004 Mike Wray <mike.wray@hp.com>
-
-import socket
-import threading
-from errno import EAGAIN, EINTR, EWOULDBLOCK
-    
-from xen.web import reactor, protocol
-
-from xen.lowlevel import xu
-
-from xen.xend.XendError import XendError
-from xen.xend import EventServer; eserver = EventServer.instance()
-from xen.xend.XendLogging import log
-from xen.xend import XendRoot; xroot = XendRoot.instance()
-from xen.xend import sxp
-from xen.xend.xenstore import DBVar
-
-from xen.xend.server.controller import CtrlMsgRcvr, Dev, DevController
-from xen.xend.server.messages import *
-from xen.xend.server.params import *
-
-class ConsoleProtocol(protocol.Protocol):
-    """Asynchronous handler for a console socket.
-    """
-
-    def __init__(self, console, id):
-        self.console = console
-        self.id = id
-        self.addr = None
-
-    def connectionMade(self, addr=None):
-        peer = self.transport.getPeer()
-        self.addr = addr
-        if self.console.connect(self.addr, self):
-            self.transport.write("Cannot connect to console %d on domain %d\n"
-                                 % (self.id, self.console.getDomain()))
-            self.loseConnection()
-            return
-        else:
-            if len(self.addr) == 2:
-                host = str(self.addr[0])
-                port = str(self.addr[1])
-            else:
-                host = 'localhost'
-                port = str(addr)
-            log.info("Console connected %s %s %s",
-                     self.id, host, port)
-            eserver.inject('xend.console.connect',
-                           [self.id, host, port])
-
-    def dataReceived(self, data):
-        if self.console.receiveInput(self, data):
-            self.loseConnection()
-
-    def write(self, data):
-        self.transport.write(data)
-        return len(data)
-
-    def connectionLost(self, reason=None):
-        log.info("Console disconnected %s %s %s",
-                 str(self.id), str(self.addr[0]), str(self.addr[1]))
-        eserver.inject('xend.console.disconnect',
-                       [self.id, self.addr[0], self.addr[1]])
-        self.console.disconnect(conn=self)
-
-    def loseConnection(self):
-        self.transport.loseConnection()
-
-class ConsoleDev(Dev, protocol.ServerFactory):
-    """Console device for a domain.
-    Does not poll for i/o itself, but relies on the domain to post console
-    output and the connected TCP sockets to post console input.
-    """
-
-    STATUS_NEW       = 'new'
-    STATUS_CLOSED    = 'closed'
-    STATUS_CONNECTED = 'connected'
-    STATUS_LISTENING = 'listening'
-
-    __exports__ = Dev.__exports__ + [
-        DBVar('status',       ty='str'),
-        #DBVar('listening',    ty='str'),
-        DBVar('console_port', ty='int'),
-        ]
-
-    def __init__(self, controller, id, config, recreate=False):
-        Dev.__init__(self, controller, id, config)
-        self.lock = threading.RLock()
-        self.status = self.STATUS_NEW
-        self.addr = None
-        self.conn = None
-        self.console_port = None
-        self.obuf = xu.buffer()
-        self.ibuf = xu.buffer()
-        self.channel = None
-        self.listening = False
-        self.unix_listener = None
-        self.tcp_listener = None
-        
-        console_port = sxp.child_value(self.config, "console_port")
-        if console_port is None:
-            console_port = xroot.get_console_port_base() + self.getDomain()
-        self.checkConsolePort(console_port)
-        self.console_port = console_port
-        
-        log.info("Created console id=%d domain=%d port=%d",
-                 self.id, self.getDomain(), self.console_port)
-        eserver.inject('xend.console.create',
-                       [self.id, self.getDomain(), self.console_port])
-
-    def init(self, recreate=False, reboot=False):
-        try:
-            self.lock.acquire()
-            self.destroyed = False
-            self.channel = self.getChannel()
-            self.listen()
-        finally:
-            self.lock.release()
-
-    def checkConsolePort(self, console_port):
-        """Check that a console port is not in use by another console.
-        """
-        xd = XendRoot.get_component('xen.xend.XendDomain')
-        for vm in xd.list():
-            ctrl = vm.getDeviceController(self.getType(), error=False)
-            if (not ctrl): continue
-            ctrl.checkConsolePort(console_port)
-    
-    def sxpr(self):
-        try:
-            self.lock.acquire()
-            val = ['console',
-                   ['status', self.status ],
-                   ['id',     self.id    ],
-                   ['domain', self.getDomain() ] ]
-            val.append(['local_port',   self.getLocalPort()  ])
-            val.append(['remote_port',  self.getRemotePort() ])
-            val.append(['console_port', self.console_port    ])
-            if self.addr:
-                val.append(['connected', self.addr[0], self.addr[1]])
-        finally:
-            self.lock.release()
-        return val
-
-    def getLocalPort(self):
-        try:
-            self.lock.acquire()
-            if self.channel:
-                return self.channel.getLocalPort()
-            else:
-                return 0
-        finally:
-            self.lock.release()
-
-    def getRemotePort(self):
-        try:
-            self.lock.acquire()
-            if self.channel:
-                return self.channel.getRemotePort()
-            else:
-                return 0
-        finally:
-            self.lock.release()
-
-    def uri(self):
-        """Get the uri to use to connect to the console.
-        This will be a telnet: uri.
-
-        return uri
-        """
-        host = socket.gethostname()
-        return "telnet://%s:%d" % (host, self.console_port)
-
-    def closed(self):
-        return self.status == self.STATUS_CLOSED
-
-    def connected(self):
-        return self.status == self.STATUS_CONNECTED
-
-    def destroy(self, change=False, reboot=False):
-        """Close the console.
-        """
-        if reboot:
-            return
-        try:
-            self.lock.acquire()
-            self.status = self.STATUS_CLOSED
-            self.listening = False
-            if self.conn:
-                self.conn.loseConnection()
-            if self.tcp_listener:
-                self.tcp_listener.stopListening()
-                self.tcp_listener = None
-            if self.unix_listener:
-                self.unix_listener.stopListening()
-                self.unix_listener = None
-        finally:
-            self.lock.release()
-
-    def listen(self):
-        """Listen for TCP connections to the console port..
-        """
-        try:
-            self.lock.acquire()
-            if self.closed():
-                return
-            if self.listening:
-                pass
-            else:
-                self.listening = True
-                self.status = self.STATUS_LISTENING
-                if xroot.get_xend_unix_server():
-                    path = '/var/lib/xend/console-%s' % self.console_port
-                    self.unix_listener = reactor.listenUNIX(path, self)
-                if xroot.get_xend_http_server():
-                    interface = xroot.get_console_address()
-                    self.tcp_listener = reactor.listenTCP(
-                        self.console_port, self, interface=interface)
-        finally:
-            self.lock.release()
-
-    def buildProtocol(self, addr):
-        """Factory function called to create the protocol when a connection is accepted
-        by listenTCP.
-        """
-        proto = ConsoleProtocol(self, self.id)
-        proto.factory = self
-        return proto
-
-    def connect(self, addr, conn):
-        """Connect a TCP connection to the console.
-        Fails if closed or already connected.
-
-        addr peer address
-        conn connection
-
-        returns 0 if ok, negative otherwise
-        """
-        try:
-            self.lock.acquire()
-            if self.closed():
-                return -1
-            if self.connected():
-                return -1
-            self.addr = addr
-            self.conn = conn
-            self.status = self.STATUS_CONNECTED
-            self.writeOutput()
-        finally:
-            self.lock.release()
-        return 0
-
-    def disconnect(self, conn=None):
-        """Disconnect the TCP connection to the console.
-        """
-        try:
-            self.lock.acquire()
-            if conn and conn != self.conn: return
-            if self.conn:
-                self.conn.loseConnection()
-            self.addr = None
-            self.conn = None
-            self.status = self.STATUS_LISTENING
-            self.listen()
-        finally:
-            self.lock.release()
-
-    def receiveOutput(self, msg):
-        """Receive output console data from the console channel.
-
-        msg     console message
-        type    major message type
-        subtype minor message typ
-        """
-        # Treat the obuf as a ring buffer.
-        try:
-            self.lock.acquire()
-            data = msg.get_payload()
-            data_n = len(data)
-            if self.obuf.space() < data_n:
-                self.obuf.discard(data_n)
-            if self.obuf.space() < data_n:
-                data = data[-self.obuf.space():]
-            self.obuf.write(data)
-            self.writeOutput()
-        finally:
-            self.lock.release()
-        
-    def writeOutput(self):
-        """Handle buffered output from the console device.
-        Sends it to the connected TCP connection (if any).
-        """
-        try:
-            self.lock.acquire()
-            if self.closed():
-                return -1
-            writes = 0
-            while self.conn and (writes < 100) and (not self.obuf.empty()):
-                try:
-                    writes += 1
-                    bytes = self.conn.write(self.obuf.peek())
-                    if bytes > 0:
-                        self.obuf.discard(bytes)
-                except socket.error, err:
-                    if err.args[0] in (EWOULDBLOCK, EAGAIN, EINTR):
-                        pass
-                    else:
-                        self.disconnect()
-                        break
-                        
-        finally:
-            self.lock.release()
-        return 0
-    
-    def receiveInput(self, conn, data):
-        """Receive console input from a TCP connection.  Ignores the
-        input if the calling connection (conn) is not the one
-        connected to the console (self.conn).
-
-        conn connection
-        data input data
-        """
-        try:
-            self.lock.acquire()
-            if self.closed(): return -1
-            if conn != self.conn: return 0
-            self.ibuf.write(data)
-            self.writeInput()
-        finally:
-            self.lock.release()
-        return 0
-
-    def writeInput(self):
-        """Write pending console input to the console channel.
-        Writes as much to the channel as it can.
-        """
-        try:
-            self.lock.acquire()
-            while self.channel and not self.ibuf.empty():
-                msg = xu.message(CMSG_CONSOLE, 0, 0)
-                msg.append_payload(self.ibuf.read(msg.MAX_PAYLOAD))
-                self.channel.writeRequest(msg)
-        finally:
-            self.lock.release()
-
-class ConsoleController(DevController):
-    """Device controller for all the consoles for a domain.
-    """
-
-    def __init__(self, vm, recreate=False):
-        DevController.__init__(self, vm, recreate=recreate)
-        self.rcvr = None
-
-    def initController(self, recreate=False, reboot=False):
-        self.destroyed = False
-        self.rcvr = CtrlMsgRcvr(self.getChannel())
-        self.rcvr.addHandler(CMSG_CONSOLE,
-                             0,
-                             self.receiveOutput)
-        self.rcvr.registerChannel()
-        if reboot:
-            self.rebootDevices()
-
-    def destroyController(self, reboot=False):
-        self.destroyed = True
-        self.destroyDevices(reboot=reboot)
-        self.rcvr.deregisterChannel()
-
-    def newDevice(self, id, config, recreate=False):
-        return ConsoleDev(self, id, config, recreate=recreate)
-
-    def checkConsolePort(self, console_port):
-        """Check that a console port is not in use by a console.
-        """
-        for c in self.getDevices():
-            if c.console_port == console_port:
-                raise XendError('console port in use: ' + str(console_port))
-
-    def receiveOutput(self, msg):
-        """Handle a control request.
-        The CMSG_CONSOLE messages just contain data, and no console id,
-        so just send to console 0 (if there is one).
-
-        todo: extend CMSG_CONSOLE to support more than one console?
-        """
-        console = self.getDevice(0)
-        if console:
-            console.receiveOutput(msg)
-        else:
-            log.warning('no console: domain %d', self.getDomain())
-
index f16c786c3ef51e1969b5591367d12e23731bf50a..0346fee43ebaf8c8b91e60e6502b3604a420fd2a 100644 (file)
@@ -128,16 +128,8 @@ class EventProtocol(protocol.Protocol):
     def op_pretty(self, name, req):
         self.pretty = 1
 
-    def op_console_disconnect(self, name, req):
-        id = sxp.child_value(req, 'id')
-        if not id:
-            raise XendError('Missing console id')
-        id = int(id)
-        self.daemon.console_disconnect(id)
-
     def op_info(self, name, req):
         val = ['info']
-        #val += self.daemon.consoles()
         #val += self.daemon.blkifs()
         #val += self.daemon.netifs()
         #val += self.daemon.usbifs()
index 84fc738e686efe2111b2ff77dc1c3db1f6616bba..9c9e405a7ad3e478c8d60a86a9c17a193c28014f 100644 (file)
@@ -17,16 +17,6 @@ See below.
 """
 msg_formats = {}
 
-#============================================================================
-# Console message types.
-#============================================================================
-
-CMSG_CONSOLE  = 0
-
-console_formats = { 'console_data': (CMSG_CONSOLE, 0) }
-
-msg_formats.update(console_formats)
-
 #============================================================================
 # Block interface message types.
 #============================================================================
index 6b4d8a27eddbd0df272363adb989620e4f4d2765..cfae6d0b87e1af59ee203ad59047b9bce684fb16 100644 (file)
@@ -7,6 +7,7 @@ import random
 import string
 import sys
 import socket
+import commands
 
 import xen.lowlevel.xc
 
@@ -17,8 +18,6 @@ from xen.xend.XendBootloader import bootloader
 from xen.xend import XendRoot; xroot = XendRoot.instance()
 from xen.util import blkif
 
-from xen.util import console_client
-
 from xen.xm.opts import *
 
 gopts = Opts(use="""[options] [vars]
@@ -145,10 +144,6 @@ gopts.var('cpu_weight', val='WEIGHT',
           use="""Set the new domain's cpu weight.
           WEIGHT is a float that controls the domain's share of the cpu.""")
 
-gopts.var('console', val='PORT',
-          fn=set_int, default=None,
-          use="Console port to use. Default is 9600 + domain id.")
-
 gopts.var('restart', val='onreboot|always|never',
           fn=set_value, default=None,
           use="""Whether the domain should be restarted on exit.
@@ -471,8 +466,6 @@ def make_config(opts, vals):
         config.append(['backend', ['netif']])
     if vals.restart:
         config.append(['restart', vals.restart])
-    if vals.console:
-        config.append(['console', vals.console])
 
     if vals.bootloader:
         run_bootloader(opts, config, vals)
@@ -620,8 +613,8 @@ def make_domain(opts, config):
 
     @param opts:   options
     @param config: configuration
-    @return: domain id, console port
-    @rtype:  (int, int)
+    @return: domain id
+    @rtype:  int
     """
 
     try:
@@ -634,19 +627,13 @@ def make_domain(opts, config):
         opts.err(str(ex))
 
     dom = sxp.child_value(dominfo, 'name')
-    console_info = sxp.child(dominfo, 'console')
-    if console_info:
-        console_port = int(sxp.child_value(console_info, 'console_port'))
-    else:
-        console_port = None
 
     if not opts.vals.paused:
         if server.xend_domain_unpause(dom) < 0:
             server.xend_domain_destroy(dom)
             opts.err("Failed to unpause domain %s" % dom)
-    opts.info("Started domain %s, console on port %d"
-              % (dom, console_port))
-    return (dom, console_port)
+    opts.info("Started domain %s" % (dom))
+    return int(sxp.child_value(dominfo, 'id'))
 
 def get_dom0_alloc():
     """Return current allocation memory of dom0 (in MB). Return 0 on error"""
@@ -709,10 +696,10 @@ def main(argv):
         if dom0_min_mem != 0:
             balloon_out(dom0_min_mem, opts)
 
-        (dom, console) = make_domain(opts, config)
+        dom = make_domain(opts, config)
         if opts.vals.console_autoconnect:
-            path = "/var/lib/xend/console-%s" % console
-            console_client.connect('localhost', console, path=path)
+            cmd = "/usr/libexec/xen/xc_console %d" % dom
+            os.execvp('/usr/libexec/xen/xc_console', cmd.split())
         
 if __name__ == '__main__':
     main(sys.argv)
index 141da198ca96c01b504830fb30a398649bfad86f..d8903801036654991c0074b9f7f49e16d9ed55c8 100644 (file)
@@ -4,6 +4,7 @@
 import os
 import os.path
 import sys
+import commands
 from getopt import getopt
 import socket
 import warnings
@@ -390,7 +391,7 @@ class ProgList(Prog):
             self.brief_list(doms)
 
     def brief_list(self, doms):
-        print 'Name              Id  Mem(MB)  CPU VCPU(s)  State  Time(s)  Console'
+        print 'Name              Id  Mem(MB)  CPU VCPU(s)  State  Time(s)'
         for dom in doms:
             info = server.xend_domain(dom)
             d = {}
@@ -401,19 +402,14 @@ class ProgList(Prog):
             d['vcpus'] = int(sxp.child_value(info, 'vcpus', '0'))
             d['state'] = sxp.child_value(info, 'state', '??')
             d['cpu_time'] = float(sxp.child_value(info, 'cpu_time', '0'))
-            console = sxp.child(info, 'console')
-            if console:
-                d['port'] = sxp.child_value(console, 'console_port')
-            else:
-                d['port'] = ''
             if d['vcpus'] > 1:
                 d['cpu'] = '-'
             if ((int(sxp.child_value(info, 'ssidref', '0'))) != 0):
                 d['ssidref1'] =  int(sxp.child_value(info, 'ssidref', '0')) & 0xffff
                 d['ssidref2'] = (int(sxp.child_value(info, 'ssidref', '0')) >> 16) & 0xffff
-                print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3s  %(vcpus)5d   %(state)5s  %(cpu_time)7.1f     %(port)4s    s:%(ssidref2)02x/p:%(ssidref1)02x" % d)
+                print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3s  %(vcpus)5d   %(state)5s  %(cpu_time)7.1f     %s:%(ssidref2)02x/p:%(ssidref1)02x" % d)
             else:
-                print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3s  %(vcpus)5d   %(state)5s  %(cpu_time)7.1f     %(port)4s" % d)
+                print ("%(name)-16s %(dom)3d  %(mem)7d  %(cpu)3s  %(vcpus)5d   %(state)5s  %(cpu_time)7.1f" % d)
 
     def show_vcpus(self, doms):
         print 'Name              Id  VCPU  CPU  CPUMAP'
@@ -699,29 +695,6 @@ class ProgInfo(Prog):
 
 xm.prog(ProgInfo)
 
-class ProgConsoles(Prog):
-    group = 'console'
-    name = "consoles"
-    info = """Get information about domain consoles."""
-
-    def main(self, args):
-        l = server.xend_consoles()
-        print "Dom Port  Id Connection"
-        for x in l:
-            info = server.xend_console(x)
-            d = {}
-            d['dom'] = sxp.child(info, 'domain', '?')[1]
-            d['port'] = sxp.child_value(info, 'console_port', '?')
-            d['id'] = sxp.child_value(info, 'id', '?')
-            connected = sxp.child(info, 'connected')
-            if connected:
-                d['conn'] = '%s:%s' % (connected[1], connected[2])
-            else:
-                d['conn'] = ''
-            print "%(dom)3s %(port)4s %(id)3s %(conn)s" % d
-
-xm.prog(ProgConsoles)
-
 class ProgConsole(Prog):
     group = 'console'
     name = "console"
@@ -735,13 +708,9 @@ class ProgConsole(Prog):
         if len(args) < 2: self.err("%s: Missing domain" % args[0])
         dom = args[1]
         info = server.xend_domain(dom)
-        console = sxp.child(info, "console")
-        if not console:
-            self.err("No console information")
-        port = sxp.child_value(console, "console_port")
-        from xen.util import console_client
-        path = "/var/lib/xend/console-%s" % port
-        console_client.connect("localhost", int(port), path=path)
+        domid = int(sxp.child_value(info, 'id', '-1'))
+        cmd = "/usr/libexec/xen/xc_console %d" % domid
+        os.execvp('/usr/libexec/xen/xc_console', cmd.split())
 
 xm.prog(ProgConsole)